/*
 * Created on 3/Abr/2004
 *
 * To change the template for this generated file go to
 * Window&gt;Preferences&gt;Java&gt;Code Generation&gt;Code and Comments
 */
package org.cyborgas.xmltool;

import java.io.File;
import java.net.URI;

import org.cyborgas.swt.RecentFileList;
import org.cyborgas.xmltool.actions.CollapseTreeAction;
import org.cyborgas.xmltool.actions.ExitAction;
import org.cyborgas.xmltool.actions.ExpandTreeAction;
import org.cyborgas.xmltool.actions.FileOpenAction;
import org.cyborgas.xmltool.actions.HelpAboutAction;
import org.cyborgas.xmltool.actions.OptionsAction;
import org.cyborgas.xmltool.actions.UrlOpenAction;
import org.cyborgas.xmltool.tabsheets.XPathTab;
import org.cyborgas.xmltool.tabsheets.XmlEditTab;
import org.cyborgas.xmltool.tabsheets.XmlViewTab;
import org.cyborgas.xmltool.tabsheets.XslTransformTab;
import org.dom4j.Document;
import org.dom4j.Node;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.window.ApplicationWindow;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.TabFolder;
import org.eclipse.swt.widgets.TabItem;
import org.eclipse.swt.widgets.Tree;


/**
 * @author rino
 *
 * To change the template for this generated type comment go to
 * Window&gt;Preferences&gt;Java&gt;Code Generation&gt;Code and Comments
 */
public class MainWindow extends ApplicationWindow {

	public static void main(String[] args) {
        Display.setAppName("XmlTool");
		MainWindow w = new MainWindow();
		w.setBlockOnOpen(true);
		w.open();
//        while (!w.getShell().isDisposed()) {
//            if (!w.getShell().getDisplay().readAndDispatch()) w.getShell().getDisplay().sleep();
//        }
		Display.getCurrent().dispose();
	}

	public final static int XML_VIEW = 0;
	public final static int XSL_EDIT = 1;
	public final static int XPATH_TAB = 2;
	public final static int XSL_TRANSFORM_TAB = 3;

	public MyXmlDocument xmlDocument = null;

	private XmlViewTab xmlViewTab;
	private XmlEditTab xmlEditTab;
	private XPathTab xPathTab;
	private XslTransformTab xslTab;
	
	// controls
	public TreeViewer docTreeView;
	public TabFolder tabFolder;
	public RecentFileList mru;

	public MainWindow() {
		super(null);
		xmlViewTab = new XmlViewTab(this);
		xmlEditTab = new XmlEditTab(this);
		xPathTab = new XPathTab(this);
		xslTab = new XslTransformTab(this);

		addMenuBar();
		addStatusLine();
		
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jface.window.Window#createContents(org.eclipse.swt.widgets.Composite)
	 */
	protected Control createContents(Composite parent) {
		
		// containers start
		SashForm sashForm = new SashForm(parent, SWT.HORIZONTAL);

		Composite leftPane = new Composite(sashForm, SWT.NONE);
		leftPane.setLayout(new FillLayout());
		
		Composite rightPane = new Composite(sashForm, SWT.NONE);
		rightPane.setLayout(new FillLayout());
		tabFolder = new TabFolder(rightPane, SWT.NONE);
		TabItem xmlViewTabItem = new TabItem(tabFolder, SWT.NONE);
		xmlViewTabItem.setText("Document");
		TabItem xmlEditTabItem = new TabItem(tabFolder, SWT.NONE);
		xmlEditTabItem.setText("Edit");
		TabItem xPathTabItem = new TabItem(tabFolder, SWT.NONE);
		xPathTabItem.setText("XPath Query");
		xPathTabItem.setImage(Util.getImageResource("XPathTab"));
		TabItem xslTabItem = new TabItem(tabFolder, SWT.NONE);
		xslTabItem.setText("XSL Transform");
		xslTabItem.setImage(Util.getImageResource("XslTransformTab"));

		// containers end

		// controls start
		getShell().setText("Xml Tool");
		getShell().setImage(Util.getImageResource("XmlTool"));
		getShell().setSize(600, 500);

		docTreeView = new TreeViewer(leftPane);
		docTreeView.setContentProvider(new XmlTreeContentProvider());
		docTreeView.setLabelProvider(new XmlLabelProvider());
		createTreeContextMenu();
		
		xmlViewTabItem.setControl(xmlViewTab.createControls(tabFolder));		
		xmlEditTabItem.setControl(xmlEditTab.createControls(tabFolder));		
		xPathTabItem.setControl(xPathTab.createControls(tabFolder));		
		xslTabItem.setControl(xslTab.createControls(tabFolder));		
		// controls end

		sashForm.setWeights(new int[] { 1, 2 });
		sashForm.pack();

		tabFolder.setSelection(XPATH_TAB);

		return sashForm;
	}



	/* (non-Javadoc)
	 * @see org.eclipse.jface.window.ApplicationWindow#createMenuManager()
	 */
	protected MenuManager createMenuManager() {
		MenuManager mainMenu = new MenuManager("");

		MenuManager fileMenu = new MenuManager("&File");
//		MenuManager editMenu = new MenuManager("&Edit");
		MenuManager toolsMenu = new MenuManager("&Tools");
		MenuManager helpMenu = new MenuManager("&Help");

		mainMenu.add(fileMenu);
//		mainMenu.add(editMenu);
		mainMenu.add(xPathTab.createMenu());
		mainMenu.add(xslTab.createMenu());
		mainMenu.add(toolsMenu);
		mainMenu.add(helpMenu);

		fileMenu.add(new FileOpenAction(this));
		fileMenu.add(new UrlOpenAction(this));
		mru = new RecentFileList(fileMenu, Util.preferences);
		fileMenu.add(new Separator());
		fileMenu.add(new ExitAction(this));

		toolsMenu.add(new OptionsAction(this));

//		helpMenu.add(new FileOpenAction(this));
//		helpMenu.add(new Separator());
		helpMenu.add(new HelpAboutAction(this));
		
		mru.addListener(new Listener() {
			public void handleEvent(Event event) {
				load((URI) event.data);
			}
		});

		return mainMenu;
	}

	private void createTreeContextMenu() {
		TreeViewer treeViewer = docTreeView;
		Tree tree = treeViewer.getTree();
		MenuManager contextMenu = new MenuManager();

		contextMenu.add(new ExpandTreeAction(treeViewer, 2));
		contextMenu.add(new ExpandTreeAction(treeViewer, 3));
		contextMenu.add(new ExpandTreeAction(treeViewer, 4));
		contextMenu.add(new ExpandTreeAction(treeViewer, -1));
//		contextMenu.add(new Separator());
//		contextMenu.add(new CollapseTreeAction(treeViewer, 2));
//		contextMenu.add(new CollapseTreeAction(treeViewer, 3));
//		contextMenu.add(new CollapseTreeAction(treeViewer, 4));
		contextMenu.add(new CollapseTreeAction(treeViewer, -1));

		tree.setMenu(contextMenu.createContextMenu(tree));
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.jface.window.Window#close()
	 */
	public boolean close() {
		this.mru.dispose();
		this.xslTab.dispose();
		this.xmlViewTab.dispose();
		return super.close();
	}
	
	
	public void load(File file) {
		load(file.toURI());
	}

		
//	public void load(File file) {		
//		try {
//			Document document = getDocument(url);
//			xmlDocument = new MyXmlDocument(document);
//			xmlDocument.prepare();
//			docTreeView.setInput(xmlDocument.getDocument());
//			docTreeView.expandToLevel(2);
//			xmlViewTab.setText(file);
//			mru.add(file);
//		} catch (Exception e) {
//			MessageDialog.openError(getShell(), "Error loading file", 
//					"The file specified (" + file + ") couldn't be loaded. "
//					+ "Reason: 	\n\n" + e.getMessage());
//			mru.remove(file);
//		}
//	}

	public void load(final URI url) {
		try {
			//this.getStatusLineManager().getProgressMonitor().beginTask("load", IProgressMonitor.UNKNOWN);

//			Thread thread = new Thread(new Runnable() {
//				public void run() {
//					try {
			Document document = Util.getDocument(url);
			xmlDocument = new MyXmlDocument(document);
			xmlDocument.prepare();
			mru.add(url);
//					} catch (Exception e) {
//						e.printStackTrace();
//					}
//				}
//			});
//			thread.start();
//		    try {
//		        thread.join();
//		        // Finished
//		    } catch (InterruptedException e) {
//		        // Thread was interrupted
//		    }
			docTreeView.setInput(xmlDocument.getDocument());
			docTreeView.expandToLevel(2);
			xmlViewTab.setText(url);
			
			this.setMessage(url.toString() + " loaded.");
		} catch (Throwable e) {
			MessageDialog.openError(getShell(), "Error loading URL",
					"The url specified (" + url + ") couldn't be loaded. "
					+ "Reason: 	\n\n" + e.getMessage());
			mru.remove(url);
			this.setErrorMessage("Error loading " + url.toString() + ": " + e.getMessage());
		}
	}


	public Node getSelectedNode() {
		Node selectedNode = null;
		IStructuredSelection sel =
			(IStructuredSelection) this.docTreeView.getSelection();
		selectedNode = (Node) sel.getFirstElement();
		return selectedNode;
	}
	
	
	//TODO: check the dirtiness level of this function...
//	private static String readTextFile(File file) throws IOException {
//		StringBuffer sb = new StringBuffer(1024);
//		BufferedReader reader = new BufferedReader(new FileReader(file));
//				
//		char[] chars = new char[1024];
//		while( reader.read(chars) > -1){
//			sb.append(String.valueOf(chars));	
//		}
//		reader.close();
//
//		return sb.toString();
//	}
//	private static String readTextFile(String fullPathFilename) throws IOException {
//		return readTextFile(new File(fullPathFilename));
//	}
	
	public void setMessage(String message) {
//		this.getStatusLineManager().getProgressMonitor().done();
		this.getStatusLineManager().setMessage(message);		
	}
	public void setMessage(String icon, String message) {
		this.getStatusLineManager().setMessage(Util.getImageResource(icon), message);		
	}
	public void setErrorMessage(String message) {
		this.setMessage("error", message);		
	}
	public void setWarningMessage(String message) {
		this.setMessage("warning", message);		
	}
}
